﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GestionePolveriLib.BL;
using GestionePolveriLib.Facades;
using GestionePolveri2.DAL;
using System.Transactions;
using BrightIdeasSoftware;


namespace GestionePolveri2
{
    public partial class AllineamentoInventarioDialog : Form
    {
        private ScortaMinimaInfo m_scortaMinimaInfo = null;
        private LottoFacade m_lottoFacade = null;
        //private int m_causale;
        private DateTime m_dataControllo = DateTime.MinValue;

        public DateTime DataControllo
        {
            get 
            {
                m_dataControllo = DateTime.MinValue;
                foreach(Lotto2 data in (List<Lotto2>)this.objectListView1.Objects)
                {
                    if (data.DataControllo.GetValueOrDefault() > m_dataControllo)
                    {
                        m_dataControllo = data.DataControllo.GetValueOrDefault();
                    }
                }

                return m_dataControllo; 
            }
            set { m_dataControllo = value; }
        }

        public ScortaMinimaInfo ScortaMinimaInfo
        {
            get { return m_scortaMinimaInfo; }
            set
            {
                m_scortaMinimaInfo = value;

                this.label1.Text = string.Format("Codice Polvere: {0} - Descrizione: {1}", m_scortaMinimaInfo.CodicePolvere, m_scortaMinimaInfo.Descrizione);
            }
        }

        public AllineamentoInventarioDialog()
        {
            InitializeComponent();

            m_lottoFacade = new LottoFacade();

            this.objectListView1.UseCellFormatEvents = true;
            this.objectListView1.CellEditStarting += new BrightIdeasSoftware.CellEditEventHandler(objectListView1_CellEditStarting);
            this.objectListView1.CellEditFinishing += new BrightIdeasSoftware.CellEditEventHandler(objectListView1_CellEditFinishing);
            this.objectListView1.FormatCell += new EventHandler<BrightIdeasSoftware.FormatCellEventArgs>(objectListView1_FormatCell);

            if (!DesignMode)
            {
                lblLottiNulli.Visible = false;
                picNulli.Visible = false;
                chkbLottiNulli.Visible = false;

                NascondiColonne();
            }
        }

        void objectListView1_FormatCell(object sender, BrightIdeasSoftware.FormatCellEventArgs e)
        {
            Lotto2 item = (Lotto2)e.Model;

            if (item.IsLottoNC)
            {
                if (e.ColumnIndex == this.olvColumnCodiceLotto.Index)
                {
                    if (item.IsLottoNC)
                    {
                        ImageDecoration imgdec = new ImageDecoration(GestionePolveri2.Properties.Resources.lgNC, 255, ContentAlignment.MiddleRight);
                        //imgdec.ShrinkToWidth = true;
                        e.SubItem.Decoration = imgdec; // new ImageDecoration(GestionePolveri2.Properties.Resources.LottoNC2_NB, 255, ContentAlignment.MiddleRight);
                    }

                    if (item.IsLottoBlocked)
                    {
                        ImageDecoration imgdec = new ImageDecoration(GestionePolveri2.Properties.Resources.lgNC_B, 255, ContentAlignment.MiddleRight);
                        //imgdec.ShrinkToWidth = true;
                        e.SubItem.Decoration = imgdec; // new ImageDecoration(GestionePolveri2.Properties.Resources.LottoNC2, 255, ContentAlignment.MiddleRight);
                    }
                }
            }
        }

        void objectListView1_CellEditStarting(object sender, BrightIdeasSoftware.CellEditEventArgs e)
        {
            OperatorePrincipal m_OperatorePrincipale = (OperatorePrincipal)System.Threading.Thread.CurrentPrincipal;
            if (!m_OperatorePrincipale.IsInRole("Amministrazione") && !m_OperatorePrincipale.IsInRole("Verniciatura"))
            {
                MessageBox.Show("Il tuo ruolo non consente di modificare la giacenza !", "Gestione Polveri", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                e.Cancel = true;
            }
            else
            {
                if (e.Column.AspectName.Equals("DataControllo"))
                {
                    if (e.Value == null)
                    {
                        Lotto2 l = (Lotto2)e.RowObject;
                        l.DataControllo = DateTime.Now.Date;
                    }
                }

                if (e.Column.AspectName.Equals("Tipo"))
                {

                }
            }
        }

        private void objectListView1_CellEditFinishing(object sender, BrightIdeasSoftware.CellEditEventArgs e)
        {
            int index = e.ListViewItem.Index;

            if (string.IsNullOrWhiteSpace(e.NewValue.ToString()))
            {
                //MessageBox.Show("Premere Enter per confermare oppure ESC per annullare l'operazione !", "Gestione Polvere", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                e.Cancel = true;
                return;
            }

            Lotto2 pp = (Lotto2)e.RowObject;
            DateTime data;

            if (e.Column.AspectName.Equals("NuovaGiacenza"))
            {
                if (!(string.IsNullOrEmpty(e.NewValue.ToString())))
                {
                    double outValue = 0;
                    if (double.TryParse(e.NewValue.ToString(), out outValue))
                    {
                        pp.NuovaGiacenza = outValue;
                    }
                    else
                    {
                        NotificationWindow.PopupNotifier pn = new NotificationWindow.PopupNotifier();
                        pn.TitleText = "Valore inserito non corretto.\nSono validi solo valori numerici !";
                        pn.TitleFont = new System.Drawing.Font(FontFamily.GenericSansSerif, 20);
                        pn.Popup();
                    }
                }
            }

            if (e.Column.AspectName.Equals("DataControllo"))
            {
                if (!string.IsNullOrEmpty(e.NewValue.ToString()))
                {
                    if (!(DateTime.TryParse(e.NewValue.ToString(), out data)))
                    {
                        MessageBox.Show("digitare la data nel formato gg/mm/aaaa");
                    }
                    else
                    {
                        m_dataControllo = DateTime.Parse(e.NewValue.ToString());
                        ((Lotto2)e.RowObject).DataControllo = DateTime.Parse(e.NewValue.ToString());
                    }
                }
            }

            this.objectListView1.Refresh();

            this.objectListView1.SelectedIndex = index;
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            LoadLotti();
        }

        private void LoadLotti()
        {
            List<Lotto2> lotti = m_lottoFacade.GetLottiAllineamento(m_scortaMinimaInfo.ID);

            this.objectListView1.SetObjects(lotti);

            List<Lotto2> lots = m_lottoFacade.GetLottiAllineamentoNulli(m_scortaMinimaInfo.ID);

            if (lots != null)
            {
                lblLottiNulli.Visible = true;
                picNulli.Visible = true;
                chkbLottiNulli.Visible = true;
            }
            else
            {
                lblLottiNulli.Visible = false;
                picNulli.Visible = false;
                chkbLottiNulli.Visible = false;
            }
        }

        private void NascondiColonne()
        {
            this.olvColumnNoteMovimento.Width = 250;
            this.olvColumnNoteNC.Width = 250;

            this.objectListView1.AllColumns.Remove(this.olvColumnNumDDT);
            this.objectListView1.AllColumns.Remove(this.olvColumnDataDDT);

            OperatorePrincipal m_OperatorePrincipale = (OperatorePrincipal)System.Threading.Thread.CurrentPrincipal;
            if (m_OperatorePrincipale.IsInRole("Amministrazione"))
            {
                this.objectListView1.AllColumns.Remove(this.olvColumnNumFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnDataFattura);

                this.btnAnnullaDataControllo.Enabled = true;
                this.olvColumnDataControlloGiac.IsEditable = true;
            }

            if (m_OperatorePrincipale.IsInRole("Acquisti"))
            {
                this.objectListView1.AllColumns.Remove(this.olvColumnNumFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnDataFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnNuovaGiacenza);

                this.btnAnnullaDataControllo.Enabled = false;
                this.olvColumnDataControlloGiac.IsEditable = false;
            }

            if (m_OperatorePrincipale.IsInRole("Direzione"))
            {
                this.objectListView1.AllColumns.Remove(this.olvColumnNumFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnDataFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnNuovaGiacenza);

                this.btnAnnullaDataControllo.Enabled = false;
                this.btnNuovo.Enabled = false;
                this.btnSave.Enabled = false;
                this.olvColumnDataControlloGiac.IsEditable = false;
            }

            if (m_OperatorePrincipale.IsInRole("Verniciatura"))
            {
                this.objectListView1.AllColumns.Remove(this.olvColumnNuovaGiacenza);
                this.objectListView1.AllColumns.Remove(this.olvColumnPrezzoUnitario);
                this.objectListView1.AllColumns.Remove(this.olvColumnValore);
                this.objectListView1.AllColumns.Remove(this.olvColumnNumFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnDataFattura);
                //this.objectListView1.AllColumns.Remove(this.olvColumnDataControlloGiac);
                this.objectListView1.AllColumns.Remove(this.olvColumnTipo);

                this.btnAnnullaDataControllo.Visible = true;
            }

            if (m_OperatorePrincipale.IsInRole("Produzione"))
            {
                this.btnSave.Enabled = false;
                this.btnNuovo.Enabled = false;
                this.btnAnnullaDataControllo.Enabled = false;
                this.olvColumnDataControlloGiac.IsEditable = false;

                this.objectListView1.AllColumns.Remove(this.olvColumnNuovaGiacenza);
                this.objectListView1.AllColumns.Remove(this.olvColumnPrezzoUnitario);
                this.objectListView1.AllColumns.Remove(this.olvColumnValore);
                this.objectListView1.AllColumns.Remove(this.olvColumnNumFattura);
                this.objectListView1.AllColumns.Remove(this.olvColumnDataFattura);
                //this.objectListView1.AllColumns.Remove(this.olvColumnDataControlloGiac);
                this.objectListView1.AllColumns.Remove(this.olvColumnTipo);
            }

            this.objectListView1.RebuildColumns();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            bool agg = false;

            foreach (Lotto2 lot in this.objectListView1.Objects)
            {

                if (lot.NuovaGiacenza != null)
                {
                    if (lot.NuovaGiacenza > lot.Giacenza)
                    {
                        CreoMovCarico(lot);
                        agg = true;
                    }

                    if (lot.NuovaGiacenza < lot.Giacenza)
                    {
                        CreoMovScarico(lot);
                        agg = true;
                    }
                }
                else
                    //aggiorno la data controllo giacenza su tutti i carichi del lotto interessato
                    if (lot.DataControllo != null)
                    {
                        LottoFacade lf = new LottoFacade();

                        lf.AggDtCtrLotto(lot.CodLotto, lot.DataControllo.Value);
                        agg = true;
                    }
            }
            if (agg)
                MessageBox.Show("Allineamento Effettuato con successo !", "Gestione Polveri", MessageBoxButtons.OK, MessageBoxIcon.Information);
            else
                MessageBox.Show("Nessun Allineamento Effettuato !", "Gestione Polveri", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private bool CreoMovCarico(Lotto2 lotto)
        {

            bool retValue = false;

            PolvereFacade polF = new PolvereFacade();
            OrdersDatesFacade odf = new OrdersDatesFacade();

            using (TransactionScope transaction = new TransactionScope())
            {
                // inserisco prima il record relativo al lotto
                Lotto lot = new Lotto();
                lot.CodLotto = lotto.CodLotto;
                lot.NumDdt = "N.D";
                lot.DataDdt = DateTime.Now;
                lot.DataScadenzaLotto = lotto.DataScadenzaLotto;

                lot.IDPolvere = lotto.IDPolvere;
                lot.Giacenza = (double)(lotto.NuovaGiacenza - lotto.Giacenza);
                lot.PrezzoUnitario = lotto.PrezzoUnitario;
                lot.Valore = lot.Giacenza * lot.PrezzoUnitario;
                if (lotto.DataControllo != null)
                    lot.DataControllo = lotto.DataControllo.Value;
                lot.Tipo = lotto.Tipo;

                LottoFacade impl = new LottoFacade();
                long idl = impl.AddLotto(lot);

                // inserisco il record relativo al movimento
                Movimento imp = new Movimento();

                CausaliMagazzinoFacade cmf = new CausaliMagazzinoFacade();
                imp.IDCausale = cmf.GetCausaleByCod("C").ID;

                imp.DataMovimento = DateTime.Now;
                imp.DataRegistrazione = DateTime.Now;

                imp.IDPolvere = lotto.IDPolvere;
                imp.Quantita = (double)(lotto.NuovaGiacenza - lotto.Giacenza);

                MovimentiFacade mv = new MovimentiFacade();

                imp.IDFormato = lotto.IDFormato;
                imp.Formato = lotto.Formato;
                imp.NumScatole = imp.Quantita / lotto.Pezzatura;

                CausaliScaricoFacade pf = new CausaliScaricoFacade();
                imp.IDCausaleScarico = ((CausaleScarico)pf.GetCausaleScarico("I")).ID;

                imp.Note = "Allineamento inventario";
                //ImpiantoFacade fi = new ImpiantoFacade();
                //imp.IDImpianto = ((Impianto)fi.GetImpiantoByNome("Inventario")).ID;

                imp.IDOperatore = ((OperatorePrincipal)System.Threading.Thread.CurrentPrincipal).Operatore.ID;
                imp.IDLotto = idl;

                MovimentiFacade impf = new MovimentiFacade();
                impf.AddMovimento(imp);

                // gestione dello stato di movimentazione del lotto...
                impl.UpdateStatoMovimentazione(idl, false);

                //aggiorno la data controllo giacenza su tutti i carichi del lotto interessato
                if (!(lotto.DataControllo == null))
                {
                    impl.AggDtCtrLotto(lotto.CodLotto, lotto.DataControllo.Value);
                }

                // gestione dello stato di riordino...
                Polvere m_polvere = polF.GetScortaMinimaInfo(imp.IDPolvere);
                if (m_polvere.QuantitaDisponibile > m_polvere.ScortaMinima)
                {
                    odf.SetOrderCloseDateByCorrection(imp.IDPolvere);
                }

                transaction.Complete();

                //MessageBox.Show("Inserimento Effettuato con successo !", "Gestione Polveri", MessageBoxButtons.OK, MessageBoxIcon.Information);

                retValue = true;
            }

            //btnCreatePolvereXXXX.Enabled = false;

            //    OnLoadData(EventArgs.Empty);
            //}

            return retValue;
        }

        private bool CreoMovScarico(Lotto2 lotto)
        {
            bool retValue = false;

            using (System.Transactions.TransactionScope transaction = new System.Transactions.TransactionScope())
            {
                // inserisco il record relativo al movimento di scarico
                Movimento imp = new Movimento();
                imp.GiacenzaInsufficienteFlag = false;
                imp.SottoScortaFlag = false;

                CausaliMagazzinoFacade cmf = new CausaliMagazzinoFacade();
                imp.IDCausale = cmf.GetCausaleByCod("S").ID;

                imp.DataMovimento = DateTime.Now;
                imp.DataRegistrazione = DateTime.Now;

                imp.IDPolvere = lotto.IDPolvere;

                MovimentiFacade mv = new MovimentiFacade();

                int m_causale = cmf.GetCausaleByCod("C").ID;
                Movimento2 mov = (Movimento2)mv.GetMovimentoByLotto(lotto.IDLotto, m_causale);
                imp.IDFormato = mov.IDFormato;
                imp.Formato = mov.Formato;

                imp.Quantita = (double)(lotto.Giacenza - lotto.NuovaGiacenza);

                imp.NumScatole = imp.Quantita / mov.Pezzatura;

                //imp.Giacenza = lotto.NuovaGiacenza;
                //imp.Valore = imp.Giacenza * lotto.PrezzoUnitario;

                imp.Note = "Allineamento inventario";
                ImpiantoFacade fi = new ImpiantoFacade();
                imp.IDImpianto = ((Impianto)fi.GetImpiantoByNome("Inventario")).ID;


                imp.IDOperatore = ((OperatorePrincipal)System.Threading.Thread.CurrentPrincipal).Operatore.ID;
                imp.IDLotto = lotto.IDLotto;

                CausaliScaricoFacade pf = new CausaliScaricoFacade();
                imp.IDCausaleScarico = ((CausaleScarico)pf.GetCausaleScarico("I")).ID;

                // definisco le informazioni di partita dummy per indicare che il lotto è conforme...
                ColoriFacade colFac = new ColoriFacade();
                Colore m_colore = colFac.Get("ND RAL");

                MovimentiFacade impf = new MovimentiFacade();
                impf.AddMovimento(imp);

                PartitaInfo m_partitaInfo = new PartitaInfo();
                m_partitaInfo.FlagConforme = true;
                m_partitaInfo.Movimento = imp;
                m_partitaInfo.ColoreVerniciato = m_colore;
                imp.Partita = m_partitaInfo;
                PartiteFacade partFac = new PartiteFacade();
                partFac.AddOrModify(m_partitaInfo);
                // definisco le informazioni di partita dummy per indicare che il lotto è conforme...

                // gestione dello stato di movimentazione del lotto...
                LottoFacade lot = new LottoFacade();
                lot.UpdateStatoMovimentazione(imp.IDLotto, true);

                // aggiunge i colori associati alla polvere movimentata nello storico colori movimenti...
                ComposizioneColoreFacadeExt ccf = new ComposizioneColoreFacadeExt();
                List<Colore> m_coloriAssociati = ccf.GetColoriAssociati(lotto.IDPolvere);
                impf.AddToStoricoColoriMovimenti(imp.IDMovimento, m_coloriAssociati, "I");

                // aggiunge la traccia nello storico movimenti...
                //impf.AddToStoricoMovimenti(imp);

                //Aggiorno la giacenza lotto                    
                lot.AggLotto(lotto.IDLotto, imp.Quantita);

                //aggiorno la data controllo giacenza su tutti i carichi del lotto interessato
                if (!(lotto.DataControllo == null))
                {
                    lot.AggDtCtrLotto(lotto.CodLotto, lotto.DataControllo.Value);
                }

                //impf.AddToStoricoMovimenti(imp);

                transaction.Complete();

                retValue = true;
            }

            return retValue;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnNuovo_Click(object sender, EventArgs e)
        {
            NuovoLottoDialog nld = new NuovoLottoDialog();
            nld.PolvereInfo = m_scortaMinimaInfo;
            if (nld.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (nld.LottoInfo.CodLotto != null)
                {
                    Lotto2 l = new Lotto2();
                    l.CodLotto = nld.LottoInfo.CodLotto;
                    l.DataDdt = DateTime.Now;
                    l.NumDdt = "N.D";
                    l.IDPolvere = nld.PolvereInfo.ID;
                    l.DataScadenzaLotto = nld.LottoInfo.DataScadenzaLotto;
                    l.Giacenza = nld.LottoInfo.Giacenza;
                    l.NuovaGiacenza = nld.LottoInfo.NuovaGiacenza;
                    l.IDFormato = nld.LottoInfo.IDFormato;
                    l.Formato = nld.LottoInfo.Formato;
                    l.Pezzatura = nld.LottoInfo.Pezzatura;
                    l.PrezzoUnitario = AssegnaPrezzoDefault(nld.LottoInfo.CodLotto, nld.PolvereInfo.ID);
                    l.Valore = l.PrezzoUnitario * l.NuovaGiacenza.GetValueOrDefault();

                    List<Lotto2> data = (List<Lotto2>)this.objectListView1.Objects;
                    data.Add(l);
                    this.objectListView1.SetObjects(data);
                }
            }
        }

        private double AssegnaPrezzoDefault(string codlotto, int idpolvere)
        {
            double prezzodefault = 0;
            LottoFacade lot = new LottoFacade();
            Lotto lotto = lot.GetUltimoCaricoLotto(codlotto);
            if (lotto == null)
            {
                lotto = lot.GetUltimoCaricoPolvere(idpolvere);
                if (lotto == null)
                    prezzodefault = 0;
                else
                    prezzodefault = lotto.PrezzoUnitario;
            }
            else
                prezzodefault = lotto.PrezzoUnitario;

            return prezzodefault;
        }

        private void chkbLottiNulli_CheckedChanged(object sender, EventArgs e)
        {
            if (chkbLottiNulli.Checked == true)
            {
                List<Lotto2> lots = m_lottoFacade.GetLotti_Nulli(m_scortaMinimaInfo.ID); //+  nulli (attivi)
                this.objectListView1.SetObjects(lots);
            }
            else
            {
                List<Lotto2> lots = m_lottoFacade.GetLottiAllineamento(m_scortaMinimaInfo.ID); //(non nulli e attivi)
                this.objectListView1.SetObjects(lots);
            }

            NascondiColonne();
        }

        private void btnAnnullaDataControllo_Click(object sender, EventArgs e)
        {
            if (this.objectListView1.SelectedObjects.Count == 0)
            {
                MessageBox.Show("Nessun elemento selezionato!", "Situazione Lotti", MessageBoxButtons.OK, MessageBoxIcon.Question);
                return;
            }

            if (MessageBox.Show("Stai per annullare la data di controllo sulla giacenza del lotto selezionato. Vuoi continuare ?",
                                "Situazione Lotti", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                if (this.objectListView1.SelectedObjects.Count > 0)
                {
                    try
                    {
                        LottoFacade lf = new LottoFacade();
                        lf.Transact(() =>
                        {
                            foreach (Lotto2 item in this.objectListView1.SelectedObjects)
                            {
                                lf.AnnullaDataControllo(item);
                            }
                        });

                        MessageBox.Show("Dati salvati correttamente !", "Situazione Lotti", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Errore durante il salvataggio dei dati: " + ex.Message, "Situazione Lotti", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    }
                }
            }
        }
    }
}
